package com.hjx.movie.common.utils.tree;

import java.io.File;
import java.util.*;

/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2021/1/16 - 17:20
 */
public class TreeBuilder<T extends TreeNode<T>> {
    List<T> nodes = new ArrayList<>();

    public TreeBuilder(){

    }
    public TreeBuilder(List<T> nodes){
        this.nodes = nodes;
    }

    public static <T extends TreeNode<T>> List<T>  builderTreeWidth(List<T> nodes,Long rootId) {
        // 队列中保存需要去寻找子节点的节点
        Queue<T> fileQueue = new ArrayDeque<>();
        List<T> tree = new ArrayList<>();
        T node;
        //查询根节点
        for(T rootNode : nodes){
            if (rootNode.getNodeId().equals(rootId)){
                fileQueue.add(rootNode);
                tree.add(rootNode);
            }
        }
        //只要队列不为空就一直循环
        while (!fileQueue.isEmpty()) {
            // 获取当前需要去找子节点的节点 并且从队列中移除
            node = fileQueue.remove();
            for (T currentNode : nodes) {
                // 如果当前节点是node的子节点
                if (currentNode.getParentId().equals(node.getNodeId())) {
                    if (node.getChildren()==null){
                        node.setChildren(new ArrayList<>());
                    }
                    // 加入到node的子节点List去
                    node.getChildren().add(currentNode);
                    //如果当前节点不是叶子节点 加入到队列中
                    if (!currentNode.getIsLeaf()){
                        fileQueue.add(currentNode);
                    }
                }
            }

        }
        return tree;
    }

    public static <T extends TreeNode<T>> List<T>  builderTreeWidthParentId(List<T> nodes,Long parentId) {
        // 队列中保存需要去寻找子节点的节点
        Queue<T> fileQueue = new ArrayDeque<>();
        List<T> tree = new ArrayList<>();
        T node;
        //查询根节点
        for(T rootNode : nodes){
            if (rootNode.getParentId().equals(parentId)){
                fileQueue.add(rootNode);
                tree.add(rootNode);
            }
        }
        //只要队列不为空就一直循环
        while (!fileQueue.isEmpty()) {
            // 获取当前需要去找子节点的节点 并且从队列中移除
            node = fileQueue.remove();
            for (T currentNode : nodes) {
                // 如果当前节点是node的子节点
                if (currentNode.getParentId().equals(node.getNodeId())) {
                    if (node.getChildren()==null){
                        node.setChildren(new ArrayList<>());
                    }
                    // 把当前节点加入到node的ChildrenList去
                    node.getChildren().add(currentNode);
                    //如果当前节点不是叶子节点 加入到队列中
                    if (!currentNode.getIsLeaf()){
                        fileQueue.add(currentNode);
                    }
                }
            }
        }
        return tree;
    }

    public static <T extends TreeNode<T>> List<T> buildTree(List<T> nodes,Long rootNodeId) {
        TreeBuilder<T> treeBuilder = new TreeBuilder<>(nodes);
        return treeBuilder.buildTree(rootNodeId);
    }
    public static <T extends TreeNode<T>> List<T> treeSort(List<T> nodes){
        nodes.sort(Comparator.comparing(TreeNode::getSort));
        for (T node : nodes) {
            if (node.getChildren()!=null&&!node.getChildren().isEmpty()) {
                treeSort(node.getChildren());
            }
        }
        return nodes;
    }

    // 构建树结构
    public List<T> buildTree(Long rootNodeId){
        List<T> treeNodes = new ArrayList<>();
        List<T> rootNodes = getRootNode(rootNodeId);
        if (!rootNodes.isEmpty()){
//            rootNodes.sort(Comparator.comparing(TreeNode::getSort));
            for (T root:rootNodes){
                buildChildNodes(root);
                treeNodes.add(root);
            }
            return treeNodes;
        }else {
            throw new IllegalArgumentException("查询不到根节点");
        }
    }
    // 递归子节点
    public void buildChildNodes(T node) {
        List<T> children = getChildNodes(node);
        if (!children.isEmpty()){
            for (T item:children){
                // 如果不是叶子 就继续找
                if (!item.getIsLeaf()){
                    buildChildNodes(item);
                }
            }
            node.setChildren(children);
        }
    }
    //获取父节点的直接子节点
    public List<T> getChildNodes(T n) {
        List<T> childrenNodes = new ArrayList<>();
        for (T node:nodes){
            if (node.getParentId().equals(n.getNodeId())){
                childrenNodes.add(node);
            }
        }
//        childrenNodes.sort(Comparator.comparing(TreeNode::getSort));
        return childrenNodes;
    }
    //查询根节点
    public List<T> getRootNode(Long rootNodeId){
        List<T> rootNodes = new ArrayList<>();
        if (rootNodeId!=null){
            for (T node:nodes){
                if (node.getNodeId().equals(rootNodeId)){
                    rootNodes.add(node);
                }
            }
        }else {
            for (T node:nodes){
                if (node.getParentId().equals(0L)){
                    rootNodes.add(node);
                }
            }
        }
        return rootNodes;
    }

}
